#!/usr/bin/python

class CRSA():
    """ RSA encrypt and decrypt """

    def __init__(self,n,e,d):
        self.n = int(n,16)
        self.e = int(e,16)
        if d:
            self.d = int(d,16)

    def bytes2int(self,bytes):
        integer = 0
        for byte in bytes:
            integer *= 256
            integer += ord(byte)

        return integer

    def int2bytes(self,number):
        string = ""

        while number > 0:
            string = "%s%s" % (chr(number & 0xFF), string)
            number /= 256
        
        return string

    def _fast_exp(self,a, p, n):
        """Calculates r = a^p mod n"""

        result = a % n
        remainders = []
        while p != 1:
            remainders.append(p & 1)
            p = p >> 1
        while remainders:
            rem = remainders.pop()
            result = ((a ** rem) * result ** 2) % n
  
        return self.int2bytes(result)

    def encrypt(self,m):
        m = self.bytes2int(m)

        return self._fast_exp(m,self.d,self.n)

    def decrypt(self,c):
        c = self.bytes2int(c)

        return self._fast_exp(c,self.e,self.n)
